using System;
using System.Runtime.InteropServices;

namespace FinMkts.Messaging.Pgm
{
    /// <summary>
    /// Specifies the Reliable Multicast send window
    /// </summary>
    /// <remarks>
    /// Any combination of the three available members may be set for a given socket option call. 
    /// For example, one, any two, or all three members may be specified during a setsockopt function call. 
    /// Regardless of settings, Windows enforces the following ratio: 
    /// TransmissionRate == (WindowSizeBytes/WindowSizeMSecs) * 8. 
    /// As such, setting any two parameters effectively sets the third to ensure optimum performance.
    /// </remarks>
    [StructLayout(LayoutKind.Sequential)]
    public class RmSendWindow
    {
        [MarshalAs(UnmanagedType.U4)]
        private uint RateKbitsPerSec;

        [MarshalAs(UnmanagedType.U4)]
        private uint WindowSizeInMSecs;

        [MarshalAs(UnmanagedType.U4)]
        private uint WindowSizeInBytes;

        /// <summary>
        /// Transmission rate for the send window per second
        /// </summary>
        public BinarySize RatePerSec
        {
            get { return BinarySize.FromKiloBits(RateKbitsPerSec); }
            set { RateKbitsPerSec = (uint) value.KiloBits; }
        }

        /// <summary>
        /// Window size for the session
        /// </summary>
        public BinarySize WindowSize
        {
            get { return BinarySize.FromBytes(WindowSizeInBytes); }
            set { WindowSizeInBytes = (uint) value.Bytes; }
        }

        /// <summary>
        /// The length of time the send window gives reliability for
        /// </summary>
        public TimeSpan WindowLength
        {
            get { return TimeSpan.FromMilliseconds(WindowSizeInMSecs);}
            set { WindowSizeInMSecs = (uint) value.TotalMilliseconds; }
        }

        public override string ToString()
        {
            return string.Format("RatePerSec: {0}, WindowLength: {1}, WindowSize: {2}", RatePerSec.ToString(BitsBytes.Bits), WindowLength, WindowSize);
        }
    }
}